package com.lswms.modules.lswms.service.impl.stock;

import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Pattern;

import com.lswms.common.utils.Result;
import com.lswms.modules.lswms.dao.base.CargojcDao;
import com.lswms.modules.lswms.dao.stock.LotDao;
import com.lswms.modules.lswms.entity.base.CargojcEntity;
import com.lswms.modules.lswms.entity.stock.LotEntity;
import com.lswms.modules.lswms.entity.stock.StockEntity;
import com.lswms.modules.lswms.service.impl.uniquecode.UniquecodeServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.groovy.runtime.typehandling.BigDecimalMath;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lswms.common.page.PageData;
import com.lswms.common.service.impl.CrudServiceImpl;
import com.lswms.modules.lswms.Constant.TaskConstant;
import com.lswms.modules.lswms.Constant.TradeConstant;
import com.lswms.modules.lswms.dao.stock.InventoryDao;
import com.lswms.modules.lswms.dao.stock.TradeDao;
import com.lswms.modules.lswms.dao.task.TaskDao;
import com.lswms.modules.lswms.dao.uniquecode.UniquecodeDao;
import com.lswms.modules.lswms.dao.uniquecode.UniquecoderecordDao;
import com.lswms.modules.lswms.dto.stock.InventoryDTO;
import com.lswms.modules.lswms.entity.stock.InventoryEntity;
import com.lswms.modules.lswms.entity.stock.TradeEntity;
import com.lswms.modules.lswms.entity.task.TaskEntity;
import com.lswms.modules.lswms.entity.uniquecode.UniquecodeEntity;
import com.lswms.modules.lswms.entity.uniquecode.UniquecoderecordEntity;
import com.lswms.modules.lswms.service.base.SequenceService;
import com.lswms.modules.lswms.service.stock.InventoryService;

import javax.swing.text.Caret;

/**
 * 属性
 *
 * @author DX sunlightcs@gmail.com
 * @since 1.0.0 2021-06-14
 */
@Service
public class InventoryServiceImpl extends CrudServiceImpl<InventoryDao, InventoryEntity, InventoryDTO>
		implements InventoryService {

	@Autowired
	private InventoryDao inventoryDao;

	@Autowired
	private LotDao lotDao;

	@Autowired
	private CargojcDao cargojcDao;

	@Autowired
	private TaskDao taskDao;

	@Autowired
	TradeDao tradeDao;

	@Autowired
	SequenceService sequenceService;

	@Autowired
	private UniquecodeServiceImpl uniquecodeService;
	
	@Autowired
	private UniquecodeDao uniquecodeDao;

	@Autowired
	private UniquecoderecordDao uniquecoderecordDao;

	@Override
	public QueryWrapper<InventoryEntity> getWrapper(Map<String, Object> params) {
		String id = (String) params.get("id");
		String sku = (String) params.get("sku");
		String descr = (String) params.get("descr");

		String location = (String) params.get("location");
		String tray = (String) params.get("tray");
		String box = (String) params.get("box");
		String lot = (String) params.get("lot");
		String qty = (String) params.get("qty");
		String pickqty = (String) params.get("pickqty");
		String putqty = (String) params.get("putqty");
		String status = (String) params.get("status");
		String lot7 = (String) params.get("lot7");
		String lot6 = (String) params.get("lot6");
		String factorycdoe = (String) params.get("factorycdoe");
		String product = (String) params.get("product");
		String sort = (String) params.get("sort");

		String jhdh = (String)params.get("jhdh");
		String chejian = (String)params.get("chejian");
		String jiage = (String)params.get("jiage");

		String[] sorts = null;
		if (StringUtils.isNotBlank(sort)) {
			sorts = sort.split("#");
		}
		
		QueryWrapper<InventoryEntity> wrapper = new QueryWrapper<>();
		wrapper.eq(StringUtils.isNotBlank(id), "lswms_inventory.id", id);
//		wrapper.eq(StringUtils.isNotBlank(sku), "lswms_inventory.sku", sku);
		wrapper.and(StringUtils.isNotBlank(sku), wrapper1-> wrapper1.eq(StringUtils.isNotBlank(sku), "lswms_inventory.sku", sku).or().eq(StringUtils.isNotBlank(sku), "lswms_sku.factorycdoe", sku) ) ;
		wrapper.like(StringUtils.isNotBlank(descr), "lswms_sku.descr", descr);
		wrapper.like(StringUtils.isNotBlank(factorycdoe), "lswms_sku.factorycdoe", factorycdoe);
		wrapper.eq(StringUtils.isNotBlank(product), "lswms_sku.product", product);
		wrapper.eq(StringUtils.isNotBlank(location), "lswms_inventory.location", location);
		wrapper.eq(StringUtils.isNotBlank(tray), "lswms_inventory.tray", tray);
		wrapper.eq(StringUtils.isNotBlank(box), "lswms_inventory.box", box);
		wrapper.eq(StringUtils.isNotBlank(lot), "lswms_inventory.lot", lot);
		wrapper.eq(StringUtils.isNotBlank(status), "lswms_inventory.status", status);
		wrapper.eq(StringUtils.isNotBlank(lot7), "lswms_lot.lot7", lot7);
		wrapper.like(StringUtils.isNotBlank(lot6), "lswms_lot.lot6", lot6);

		wrapper.eq(StringUtils.isNotBlank(jhdh),"re.lot6",jhdh);
		wrapper.like(StringUtils.isNotBlank(chejian),"re.lot7",chejian);
		wrapper.like(StringUtils.isNotBlank(jiage),"re.lot4",jiage);

		wrapper.in(sorts != null && sorts.length > 0, "lswms_sku.sort", sorts);


		setNumberQuery(wrapper, "qty", qty == null ? null : qty.trim());
		setNumberQuery(wrapper, "pickqty", pickqty == null ? null : pickqty.trim());
		setNumberQuery(wrapper, "putqty", putqty == null ? null : putqty.trim());

		wrapper.orderByDesc("lswms_inventory.sku") ;
		wrapper.orderByDesc("lswms_inventory.tray") ;
		wrapper.orderByDesc("lswms_inventory.box") ;
		
		return wrapper;
	}

	@Override
	public PageData<InventoryEntity> pageBySql(Map<String, Object> params) {
		IPage<InventoryEntity> page = baseDao.selectPageBySql(getPage(params, null, false), getWrapper(params));
		return getPageData(page, InventoryEntity.class);
	}

	private List<String> cargoLocation(){
		List<String> pid = cargojcDao.pidNos();
		return pid;
	}

	public QueryWrapper<InventoryEntity> getWrapper2(Map<String, Object> params) {
		QueryWrapper<InventoryEntity> wrapper = new QueryWrapper<>();
		return wrapper;
	}


	@Override
	public PageData<InventoryEntity> pageBySql2(Map<String, Object> params) {
		//查到了所有的库存数据
		//IPage<InventoryEntity> page = baseDao.selectPageBySql(getPage(params, null, false), getWrapper2(params));
		IPage<InventoryEntity> page2 = inventoryDao.cargojcSelect(getPage(params, null, false),getWrapper2(params));

		return getPageData(page2, InventoryEntity.class);
	}

	public QueryWrapper<InventoryEntity> getWrapper3(Map<String, Object> params) {
		QueryWrapper<InventoryEntity> wrapper = new QueryWrapper<>();
		String tray = (String) params.get("tray");
		wrapper.eq("tray",tray);
		wrapper.inSql("lswms_inventory.lot","select lot from lswms_lot where lot15 = '检测'");

		return wrapper;
	}
	@Override
	public PageData<InventoryEntity> pageBySql3(Map<String, Object> params) {


		//查该箱子内所有在检测状态的货物
		IPage<InventoryEntity> page = baseDao.selectPageBySql(getPage(params, null, false), getWrapper3(params));


		return getPageData(page, InventoryEntity.class);
	}

	@Override
	public List<InventoryEntity> byData(Map<String, Object> params) {
		List<InventoryEntity> list =baseDao.selectByData(getWrapper(params)) ;
		return list;
	}



	void setNumberQuery(QueryWrapper wrapper, String column, String value) {
		// 原符号 < <= > >= <>
		// 对应函数 lt() le() gt() ge() ne()
		// 拆分value值，去掉符号后的部分如果可以转数字，使用比较函数，否则使用eq
		if (StringUtils.isBlank(value)) {
			return;
		}

		// &gt;
		if (valideNumber(value, "&ge;")) {
			// &ge; - >
			wrapper.ge(column, value.substring(value.indexOf(">=") + 5).trim());
		} else if (valideNumber(value, "&le;")) {
			// &le; - >
			wrapper.le(column, value.substring(value.indexOf("<=") + 5).trim());
		} else if (valideNumber(value, "&ne;")) {
			// &ne; - >
			wrapper.ne(column, value.substring(value.indexOf("<>") + 5).trim());
		} else if (valideNumber(value, "&gt;")) {
			// &gt; - >
			wrapper.gt(column, value.substring(value.indexOf(">") + 5).trim());
		} else if (valideNumber(value, "&lt;")) {
			// &lt; - >
			wrapper.lt(column, value.substring(value.indexOf("<") + 5).trim());
		} else {
			// 这样写是为了在数字录入了字符，导致程序发生异常，
			// 使其无法查到数据
			wrapper.eq("qty", 0);
			wrapper.eq("qty", 2);
		}

	}

	private boolean valideNumber(String value, String ch) {
		int index = value.indexOf(ch);
		if (index == -1) {
			return false;
		}
		String st = value.substring(index + 4);
		Pattern pattern = Pattern.compile("-?[0-9]+(\\.[0-9]+)?");
		return pattern.matcher(st).matches();
	}

	public Integer checkTray(String totray) {

		Integer tray = inventoryDao.getTray(totray);
		return tray;
	}

	public Integer checkBox(String tobox) {
		Integer box = inventoryDao.getBox(tobox);
		return box;
	}

	public boolean checkReceipt(String totray, String toloc) {

		BigDecimal bigDecimal = new BigDecimal(0);
		List<BigDecimal> qtyList = inventoryDao.getQtyList(totray, toloc);
		qtyList.forEach(item -> {

		});
		return false;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String transferTray(List<InventoryEntity> list) {
//		Result result = uniquecodeService.transferTrayUniquecod(list);
//		int code = result.getCode();
//		if(code!=0){
//			return result.getMsg();
//		}
		// TODO Auto-generated method stub
		for (InventoryEntity inventoryEntity : list) {
			String location = inventoryEntity.getLocation();
			String tray = inventoryEntity.getTray();
			String box = inventoryEntity.getBox();
			String lot = inventoryEntity.getLot();
			String sku = inventoryEntity.getSku();
			BigDecimal qty = inventoryEntity.getQty();
			BigDecimal pickqty = inventoryEntity.getPickqty();
			BigDecimal putqty = inventoryEntity.getPutqty();
			String totray = inventoryEntity.getTotray();
			String tobox = inventoryEntity.getTobox();
			BigDecimal toqty = inventoryEntity.getToqty();

			if (totray == null && tobox == null && toqty == null) {
				continue;
			}
			if (totray != null && tobox != null && totray.equals(tray) && tobox.equals(box)) {
				continue;
			}

			if (totray == null) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "请输入目的托盘号";
			}
			if (tobox == null) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "请输入目的箱号";
			}
			if (toqty == null || toqty.compareTo(BigDecimal.ZERO) <= 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "请输入正数";
			}
			if (toqty.compareTo(qty) > 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "目的数量超过原有量";
			}
			/*if(sku){

			}*/
			// 校验库存是否发生了改变
			QueryWrapper<InventoryEntity> inventoryQuery = new QueryWrapper<InventoryEntity>();
			inventoryQuery.eq("location", location);
			inventoryQuery.eq("tray", tray);
			inventoryQuery.eq("box", box);
			inventoryQuery.eq("lot", lot);
			InventoryEntity inventoryEntityPre = baseDao.selectOne(inventoryQuery);
			BigDecimal qtyPre = inventoryEntityPre.getQty();
			BigDecimal pickqtyPre = inventoryEntityPre.getPickqty();
			BigDecimal putqtyPre = inventoryEntityPre.getPutqty();
			if (qty.compareTo(qtyPre) != 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "库存记录发生了变更，请重试";
			}

			if (pickqtyPre.compareTo(BigDecimal.ZERO) > 0 || putqtyPre.compareTo(BigDecimal.ZERO) > 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "托盘存在未完成的任务，不允许操作";
			}

			QueryWrapper<TaskEntity> taskQuery = new QueryWrapper<TaskEntity>();

			taskQuery.ne("status", TaskConstant.TASK_9);
			taskQuery.and(wrapper -> wrapper.eq("fromtray", tray).or().eq("totray", tray));

			Integer count = taskDao.selectCount(taskQuery);
			if (count > 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return "托盘存在未完成的任务，不允许操作";
			}

			// 当前记录行扣减库存
			UpdateWrapper<InventoryEntity> inventoryUpdate = new UpdateWrapper<InventoryEntity>();
			inventoryUpdate.eq("location", location);
			inventoryUpdate.eq("tray", tray);
			inventoryUpdate.eq("box", box);
			inventoryUpdate.eq("lot", lot);
			InventoryEntity inventoryEntityUpdate = new InventoryEntity();
			inventoryEntityUpdate.setQty(qtyPre.subtract(toqty));
			baseDao.update(inventoryEntityUpdate, inventoryUpdate);

			// 目的容器添加库存 查询目的容器是否存在库存，若有库存则更新库存，无库存则新增库存记录
			QueryWrapper<InventoryEntity> inventoryQueryTo = new QueryWrapper<InventoryEntity>();
			inventoryQueryTo.eq("location", location);
			inventoryQueryTo.eq("tray", totray);
			inventoryQueryTo.eq("box", tobox);
			inventoryQueryTo.eq("lot", lot);
			// inventoryQueryTo.gt("qty", 0) ;
			InventoryEntity inventoryEntityTo = baseDao.selectOne(inventoryQueryTo);
			if (inventoryEntityTo != null) {
				String skuTo = inventoryEntityTo.getSku();

//				if (!skuTo.equals(sku)) {
//					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//					return "目的箱里有其他物品，无法混放";
//				}

				UpdateWrapper<InventoryEntity> inventoryUpdateTo = new UpdateWrapper<InventoryEntity>();
				inventoryUpdateTo.eq("location", location);
				inventoryUpdateTo.eq("tray", totray);
				inventoryUpdateTo.eq("box", tobox);
				inventoryUpdateTo.eq("lot", lot);
				InventoryEntity inventoryEntityUpdateTo = new InventoryEntity();
				inventoryEntityUpdateTo.setQty(inventoryEntityTo.getQty().add(toqty));
				baseDao.update(inventoryEntityUpdateTo, inventoryUpdateTo);

			} else {
				InventoryEntity inventoryEntityInsert = new InventoryEntity();
				inventoryEntityInsert.setLocation(location);
				inventoryEntityInsert.setTray(totray);
				inventoryEntityInsert.setBox(tobox);
				inventoryEntityInsert.setLot(lot);
				inventoryEntityInsert.setSku(sku);
				inventoryEntityInsert.setQty(toqty);
				inventoryEntityInsert.setPickqty(BigDecimal.ZERO);
				inventoryEntityInsert.setPutqty(BigDecimal.ZERO);
				inventoryEntityInsert.setStatus(0);
				inventoryEntityInsert.setRemark("");
				baseDao.insert(inventoryEntityInsert);
			}

			String isuniquecode = inventoryEntity.getIsuniquecode();
			// 效验数据
			if (StringUtils.isNotBlank(isuniquecode) && isuniquecode.equals("1")) {
				String uniquecodeBuild = inventoryEntity.getUniquecodes() ;
				String[] uniquecodeBuilds = uniquecodeBuild.split("\n");

				List<String> uniquecodes = new LinkedList<>();
				for (String uniquecode : uniquecodeBuilds) {
					uniquecodes.add(uniquecode);
				}
				long count1 = uniquecodes.stream().distinct().count();
				if (uniquecodes.size() != count1) {
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return "请不要输入重复唯一码";
				}
//				BigDecimal backqty = inventoryEntity.getBackqty() ;
				Number number = BigDecimalMath.abs(toqty);

				int i = number.intValue();
				if (i != uniquecodes.size()) {
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return "唯一码的数量不等于实际转移数量";
				}
				for (String uniquecode : uniquecodes) {
					if (uniquecodeDao.checkUniquecode(uniquecode) > 0) {
						TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
						return "此唯一码已存在:" + uniquecode;

					}
				}

				for (String uniquecode : uniquecodes) {
					// 增加唯一码记录
					UniquecodeEntity uniquecodeEntity = new UniquecodeEntity();
					uniquecodeEntity.setSku(sku);
					//uniquecodeEntity.setReceiptkey(dto.getRecipientsbackkey());
					uniquecodeEntity.setReceipttime(new Date());
					uniquecodeEntity.setTray(totray);
					uniquecodeEntity.setBox(tobox);
					uniquecodeEntity.setLot(lot);
					uniquecodeEntity.setUniquecode(uniquecode);
					uniquecodeDao.insert(uniquecodeEntity);

					// 增加唯一码历史记录
					UniquecoderecordEntity uniquecoderecordEntity = new UniquecoderecordEntity();
					uniquecoderecordEntity.setUniquecode(uniquecode);
					uniquecoderecordEntity.setFromtray(tray);
					uniquecoderecordEntity.setFrombox(box);
					uniquecoderecordEntity.setTotray(totray);
					uniquecoderecordEntity.setTobox(tobox);
					uniquecoderecordEntity.setSku(sku);
					uniquecoderecordEntity.setLot(lot);
					uniquecoderecordEntity.setSourcetype(TradeConstant.TRADETYPE_MV);
					uniquecoderecordEntity.setSourcetable("inventory");
					uniquecoderecordEntity.setSourceid(null);
					uniquecoderecordEntity.setSourcekey(null);
					uniquecoderecordEntity.setSourceline(null);
					uniquecoderecordEntity.setSourcelinelist(null);
					uniquecoderecordDao.insert(uniquecoderecordEntity);
				}
			}
			
			
			// 新增交易记录
			String tradekey = sequenceService.getSequence("trade");
			TradeEntity tradeEntity = new TradeEntity();

			tradeEntity.setTradekey(tradekey);
			tradeEntity.setTradetype(TradeConstant.TRADETYPE_MV);
			tradeEntity.setSku(sku);
			tradeEntity.setQty(toqty);
			tradeEntity.setSourcetype(TradeConstant.SOURCETYPE_MOVE);
			tradeEntity.setSourcekey(null);
			tradeEntity.setSourceline(null);
			tradeEntity.setSourcelinelist(null);
			tradeEntity.setFromlocation(location);
			tradeEntity.setTolocation(location);
			tradeEntity.setFromtray(tray);
			tradeEntity.setTotray(totray);
			tradeEntity.setFrombox(box);
			tradeEntity.setTobox(tobox);
			tradeEntity.setFromlot(lot);
			tradeEntity.setTolot(lot);
			tradeEntity.setFromlot1(null);
			tradeEntity.setFromlot2(null);
			tradeEntity.setFromlot3("");
			tradeEntity.setFromlot4("");
			tradeEntity.setFromlot5("");
			tradeEntity.setFromlot6("");
			tradeEntity.setFromlot7("");
			tradeEntity.setFromlot8("");
			tradeEntity.setFromlot9("");
			tradeEntity.setFromlot10("");
			tradeEntity.setFromlot11("");
			tradeEntity.setFromlot12("");
			tradeEntity.setFromlot13("");
			tradeEntity.setFromlot14("");
			tradeEntity.setFromlot15("");
			tradeEntity.setTolot1(null);
			tradeEntity.setTolot2(null);
			tradeEntity.setTolot3("");
			tradeEntity.setTolot4("");
			tradeEntity.setTolot5("");
			tradeEntity.setTolot6("");
			tradeEntity.setTolot7("");
			tradeEntity.setTolot8("");
			tradeEntity.setTolot9("");
			tradeEntity.setTolot10("");
			tradeEntity.setTolot11("");
			tradeEntity.setTolot12("");
			tradeEntity.setTolot13("");
			tradeEntity.setTolot14("");
			tradeEntity.setTolot15("");
			tradeDao.insert(tradeEntity);
		}

		return null;
	}


}
